package com.uinnova.product.eam.service.es;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.PropertyFilter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.binary.core.exception.MessageException;
import com.binary.core.util.BinaryUtils;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.model.CiQueryCdtExtend;
import com.uinnova.product.eam.model.vo.ESCISearchBeanVO;
import com.uinnova.product.vmdb.comm.model.ci.CCcCi;
import com.uinnova.product.vmdb.comm.model.ci.CcCiAttrDef;
import com.uinnova.product.vmdb.comm.util.CommUtil;
import com.uinnova.product.vmdb.comm.util.PropertyType;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiClassInfo;
import com.uinnova.product.vmdb.provider.ci.bean.CcCiInfo;
import com.uinnova.product.vmdb.provider.ci.bean.CiGroupPage;
import com.uinnova.product.vmdb.provider.search.bean.CcCiSearchPage;
import com.uino.bean.cmdb.base.*;
import com.uino.bean.cmdb.query.ESAttrAggBean;
import com.uino.bean.cmdb.query.ESCISearchBean;
import com.uino.bean.permission.base.SysUser;
import com.uino.dao.AbstractESBaseDao;
import com.uino.dao.BaseConst;
import com.uino.dao.ESConst;
import com.uino.dao.cmdb.ESCIAttrTransConfigSvc;
import com.uino.dao.cmdb.ESCIClassSvc;
import com.uino.dao.cmdb.ESTagSvc;
import com.uino.dao.util.ESUtil;
import com.uino.util.sys.CheckAttrUtil;
import com.uino.util.sys.SysUtil;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.*;
import org.elasticsearch.index.search.MatchQuery;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Repository
public class IamsESCITemporarySvc extends AbstractESBaseDao<ESCIInfo, CCcCi> {

    private static final Logger log = LoggerFactory.getLogger(IamsESCIDesignSvc.class);

    @Resource
    @Lazy
    ESCIClassSvc classSvc;

    @Resource
    @Lazy
    IamsESCmdbCommDesignSvc commSvc;

    @Resource
    private IamsESCIHistoryDesignSvc ciHistorySvc;

    @Resource
    private ESCIAttrTransConfigSvc attrConfigSvc;

    @Resource
    private ESTagSvc esTagSvc;

    @Resource
    private IamsCIDesignNonComplianceDao iamsCIDesignNonComplianceDao;

    @Override
    public String getIndex() {
        return ESConst.INDEX_CMDB_CI + "_temporary";
    }

    @Override
    public String getType() {
        return "_doc";
    }

    @PostConstruct
    public void init() {
        super.initIndex();
    }

    @Override
    public XContentBuilder getMapping(String analyzerName) {
        XContentBuilder mapping = null;
        try {
            mapping = XContentFactory.jsonBuilder();
            mapping.startObject().startObject(getFullTypeName()).startObject("properties").field("id", Collections.singletonMap("type", "long")).field("createTime", Collections.singletonMap("type", "long"))
                    .field("modifyTime", Collections.singletonMap("type", "long")).endObject().field("date_detection", false).startArray("dynamic_templates").startObject().startObject("strings")
                    .field("match_mapping_type", "string").startObject("mapping").field("analyzer", analyzerName).field("type", "text").startObject("fields").startObject("keyword")
                    .field("ignore_above", "256").field("type", "keyword")/* .field("normalizer", "my_normalizer") */
                    .endObject().endObject().endObject().endObject().endObject().startObject().startObject("floats").field("match_mapping_type", "double").startObject("mapping")
                    .field("analyzer", analyzerName).field("type", "double").endObject().endObject().endObject().startObject().startObject("longs").field("match_mapping_type", "long")
                    .startObject("mapping").field("analyzer", analyzerName).field("type", "long").endObject().endObject().endObject().endArray().endObject().endObject();
        } catch (Exception e) {
            e.printStackTrace();
            log.error(e.getMessage(), e);
        }
        return mapping;
    }

    /**
     * <b>获取CICIinfo对象
     *
     * @param id
     * @return
     */
    public CcCiInfo getCiInfoById(Long id) {
        ESCIInfo esCI = this.getById(id);
        if (esCI != null) {
            CcCiInfo ciInfo = commSvc.tranCcCiInfo(esCI, false);
            List<ESCIClassInfo> classInfos = classSvc.getAllDefESClassInfosByClassIds(BaseConst.DEFAULT_DOMAIN_ID, Arrays.asList(esCI.getClassId()));
            if (!BinaryUtils.isEmpty(classInfos)) {
                ESCIClassInfo classInfo = classInfos.get(0);
                ciInfo.setCiClass(classInfo);
                ciInfo.setAttrDefs(classInfo.getCcAttrDefs());
            }
            return ciInfo;
        }
        return null;
    }

    public List<CcCiInfo> queryCiInfoList(CCcCi cdt, String orders, Boolean isAsc, Boolean hasClass) {
        if (cdt == null) {
            cdt = new CCcCi();
        }
        orders = BinaryUtils.isEmpty(orders) ? "modifyTime" : orders;
        orders = ESUtil.underlineToCamel(orders);
        QueryBuilder query = ESUtil.cdtToBuilder(cdt);
        //不count了，有效率问题
        //long count = this.countByCondition(query);
        List<ESCIInfo> list = this.getSortListByQuery(1, 10000, query, orders, isAsc).getData();
        return commSvc.transEsInfoList(list, hasClass);
    }

    public List<ESCIInfo> queryESCiInfoList(CCcCi cdt, String orders, Boolean isAsc) {
        if (cdt == null) {
            cdt = new CCcCi();
        }
        orders = BinaryUtils.isEmpty(orders) ? "modifyTime" : orders;
        orders = ESUtil.underlineToCamel(orders);
        QueryBuilder query = ESUtil.cdtToBuilder(cdt);
        long count = this.countByCondition(query);
        List<ESCIInfo> list = this.getSortListByQuery(1, new BigDecimal(count).intValue(), query, orders, isAsc ? true : false).getData();
        return list;
    }

    public Page<CcCiInfo> queryCiInfoPage(Integer pageNum, Integer pageSize, CCcCi cdt, String orders, Boolean isAsc, Boolean hasClass) {
        if (cdt == null) {
            cdt = new CCcCi();
        }
        orders = BinaryUtils.isEmpty(orders) ? "modifyTime" : orders;
        orders = ESUtil.underlineToCamel(orders);
        Page<ESCIInfo> esPage = this.getSortListByQuery(pageNum, pageSize, ESUtil.cdtToBuilder(cdt), orders, isAsc);
        return commSvc.transEsInfoPage(esPage, hasClass);
    }

    public Page<CcCiInfo> getCIInfoPageByQuery(int pageNum, int pageSize, QueryBuilder query, Boolean hasClass) {
        Page<ESCIInfo> esPage = this.getListByQuery(pageNum, pageSize, query);
        return commSvc.transEsInfoPage(esPage, hasClass);
    }

    /**
     * <b>保存到ES
     *
     * @param ciInfo
     * @return 唯一ID
     */
    public Long saveOrUpdateCI(CcCiInfo ciInfo) {
        if (BinaryUtils.isEmpty(ciInfo.getCi().getId())) {
            long id = ESUtil.getUUID();
            ciInfo.getCi().setId(id);
            ciInfo.getCi().setCiCode(String.valueOf(id));
            try {
                SysUser loginUser = SysUtil.getCurrentUserInfo();
                ciInfo.getCi().setCreator(loginUser.getLoginCode());
            } catch (Exception e) {
                ciInfo.getCi().setCreator("system");
            }
        }
        ESCIInfo esCI = commSvc.tranESCIInfo(ciInfo);
        // String jsonStr = JSON.toJSONString(esCI);
        // JSONObject json = JSON.parseObject(jsonStr);
        return this.saveOrUpdate(esCI);
    }

    /**
     * 批量保存并返回保存详情
     *
     * @param ciInfoList
     * @return
     */
    public Map<String, Object> saveOrUpdateCIBatch(List<CcCiInfo> ciInfoList, boolean isAsync) {
        // JSONArray list = new JSONArray();
        List<ESCIInfo> esciInfos = new ArrayList<>();
        SysUser loginUser = null;
        try {
            loginUser = SysUtil.getCurrentUserInfo();
        } catch (Exception e) {
        }
        for (CcCiInfo ciInfo : ciInfoList) {
            ESCIInfo esCI = commSvc.tranESCIInfo(ciInfo);
            if (esCI.getId() == null) {
                esCI.setId(ESUtil.getUUID());
                ciInfo.getCi().setCreator(loginUser == null ? "system" : loginUser.getLoginCode());
            }
            if (BinaryUtils.isEmpty(esCI.getCiCode())) {
                esCI.setCiCode(String.valueOf(esCI.getId()));
            }
            esciInfos.add(esCI);
            // String jsonStr = JSON.toJSONString(esCI);
            // JSONObject json = JSON.parseObject(jsonStr);
            // list.add(json);
        }
        this.transCIAttrs(esciInfos, false);
        ciHistorySvc.saveOrUpdateHistoryInfosBatch(esciInfos, ESCIHistoryInfo.ActionType.SAVE_OR_UPDATE);
        return this.saveOrUpdateBatchMessage(this.writeMapNullValueForAttrs(esciInfos), isAsync);
    }

    /**
     * dcv特有，不允许别人调用，否则可能有严重问题
     *
     * @param esCiInfoList
     * @return
     */
    public Integer updateESCIInfoBatch(List<ESCIInfo> esCiInfoList) {
        if (!BinaryUtils.isEmpty(esCiInfoList)) {
            Integer i = super.saveOrUpdateBatch(esCiInfoList);
            return i;
        } else {
            return 1;
        }
    }

    public List<ESCIInfo> saveOrUpdateCiList(List<ESCIInfo> ciList) {
        for (ESCIInfo ciInfo : ciList) {
            if (BinaryUtils.isEmpty(ciInfo.getId())) {
                long id = ESUtil.getUUID();
                ciInfo.setId(id);
                ciInfo.setCiCode(String.valueOf(id));
                try {
                    SysUser loginUser = SysUtil.getCurrentUserInfo();
                    ciInfo.setCreator(loginUser.getLoginCode());
                    if(BinaryUtils.isEmpty(ciInfo.getOwnerCode())){
                        ciInfo.setOwnerCode(ciInfo.getCreator());
                    }
                } catch (Exception e) {
                    ciInfo.setCreator("system");
                    if(BinaryUtils.isEmpty(ciInfo.getOwnerCode())){
                        ciInfo.setOwnerCode("system");
                    }
                }
            }
            commSvc.tranESCIInfo(ciInfo);
        }
        this.saveOrUpdateBatch(ciList);
        return ciList;
    }

    /**
     * <b>删除分类下的CI
     *
     * @param id 分类ID
     * @return
     */
    public Integer removeByClassId(Long id) {
        return super.deleteByQuery(QueryBuilders.termQuery("classId", id), true);
    }

    /**
     * 全文检索
     * @param pageNum
     * @param pageSize
     * @param cdt
     * @param hasClass
     * @return
     */
    public CiGroupPage queryPageByIndex(Integer pageNum, Integer pageSize, CiQueryCdtExtend cdt, Boolean hasClass) {
        if (hasClass == null) {
            hasClass = false;
        }
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        // 全文检索
        String like = cdt.getLike();
        if (like != null && !like.isEmpty()) {
            query.must(QueryBuilders.multiMatchQuery(like, "attrs.*").operator(Operator.AND).type(MatchQuery.Type.PHRASE_PREFIX).lenient(true));
        }
        // 根据分类id
        Long classId = cdt.getClassId();
        if (classId != null) {
            query.must(QueryBuilders.termQuery("classId", classId));
        }
        Long[] classIds = cdt.getClassIds();
        if (classIds != null) {
            query.must(QueryBuilders.termsQuery("classId", Arrays.asList(classIds)));
        }
        // 根据标签id
        Long tagId = cdt.getTagId();
        if (tagId != null) {
            ESCITagInfo tag = esTagSvc.getById(tagId);
            if (tag == null) {
                return commSvc.tranCiGroupPage(new Page<>(), false);
            }
            query.must(esTagSvc.getQueryByTag(tag));
        }
        Long[] tagIds = cdt.getTagIds();
        if (tagIds != null) {
            List<ESCITagInfo> tags = esTagSvc.getListByQueryScroll(QueryBuilders.termsQuery("id", Arrays.asList(tagIds)));
            if (tags.size() < tagIds.length) {
                return commSvc.tranCiGroupPage(new Page<>(), false);
            }
            for (ESCITagInfo tag : tags) {
                query.must(esTagSvc.getQueryByTag(tag));
            }
        }
        Page<ESCIInfo> page = this.getSortListByQuery(pageNum, pageSize, query, "modifyTime", false);
        return commSvc.tranCiGroupPage(page, hasClass);
    }

    public CiGroupPage queryPageBySearchBean(ESCISearchBean bean, Boolean hasClass) {
        Page<ESCIInfo> page = this.searchESCIByBean(bean);
        return commSvc.tranCiGroupPage(page, hasClass);
    }

    /**
     * es分页查询ci接口支持<br/>
     * 1、模糊匹配<br/>
     * 2、根据指定属性查询(and /or )<br/>
     * 3、ciCode/ciId/hashcode筛选<br/>
     * 4、classIds筛选<br/>
     * 5、tagIds筛选<br/>
     * 6、默认根据匹配度排序<br/>
     * 7、排序字段 如果是字符串类型必须加keyword
     *
     * @param bean 查询BEAN，定义了各个字段之间的关系
     * @return
     */
    public CcCiSearchPage searchCIByBean(ESCISearchBean bean) {
        return commSvc.tranCcCiSearchPage(this.searchESCIByBean(bean));
    }

    public Page<ESCIInfo> searchESCIByBean(ESCISearchBean bean) {
        QueryBuilder query = commSvc.getCIQueryBuilderByBean(bean);
        String sort = !BinaryUtils.isEmpty(bean.getSortField()) ? bean.getSortField() : "modifyTime";
        // 映射排序字段
        Set<Long> classIds = new HashSet<>();
        if (!BinaryUtils.isEmpty(bean.getClassIds())) {
            classIds.addAll(bean.getClassIds());
        }
        if (bean.getCdt() != null && bean.getCdt().getClassId() != null) {
            classIds.add(bean.getCdt().getClassId());
        }
        sort = this.transSortField(classIds, sort);
        if (bean.isHighLight()) {
            SortOrder orderType = bean.isAsc() ? SortOrder.ASC : SortOrder.DESC;
            List<SortBuilder<?>> sorts = new LinkedList<>();
            sorts.add(SortBuilders.fieldSort(sort).order(orderType));
            return this.getSortListByHighLightQuery(bean.getPageNum(), bean.getPageSize(), query, sorts, bean.getHighLightFields());
        } else {
            return this.getSortListByQuery(bean.getPageNum(), bean.getPageSize(), query, sort, bean.isAsc());
        }
    }

    /**
     * <b>根据cdt对象查询分类
     *
     * @param pageNum
     * @param pageSize
     * @param bean 自动生成的分类查询对象
     * @return
     */
    public CcCiSearchPage searchCIByCdt(int pageNum, int pageSize, CCcCi bean) {
        QueryBuilder query = ESUtil.cdtToBuilder(bean);
        Page<ESCIInfo> page = this.getSortListByQuery(pageNum, pageSize, query, "modifyTime", false);
        return commSvc.tranCcCiSearchPage(page);
    }

    public List<ESCIInfo> getCIInfoListByCIPrimaryKeys(List<List<String>> ciPrimaryKeys) {
        if (BinaryUtils.isEmpty(ciPrimaryKeys)) {
            return Collections.emptyList();
        }
        // 生成hashCodes
        Set<Integer> hashCodes = getHashCodesByPrimaryKeys(ciPrimaryKeys);
        Assert.isTrue(!BinaryUtils.isEmpty(hashCodes), "X_PARAM_NOT_NULL${name:hashCodes}");
        // 查询CI信息
        CCcCi cdt = new CCcCi();
        cdt.setHashCodes(hashCodes.toArray(new Integer[] {}));
        List<ESCIInfo> ciInfos = this.queryESCiInfoList(cdt, null, true);
        if (BinaryUtils.isEmpty(ciInfos)) {
            return Collections.emptyList();
        }
        // 分组
        Map<Integer, List<ESCIInfo>> ciHashCodeInfoMap = new HashMap<Integer, List<ESCIInfo>>();
        for (ESCIInfo info : ciInfos) {
            if (info == null) {
                // 防数据不完整
                continue;
            }
            Integer key = info.getHashCode();
            List<ESCIInfo> infos = ciHashCodeInfoMap.get(key);
            if (infos == null) {
                infos = new ArrayList<ESCIInfo>();
            }
            infos.add(info);
            ciHashCodeInfoMap.put(key, infos);
        }
        // 组装
        List<ESCIInfo> resultInfos = new ArrayList<ESCIInfo>();
        for (List<String> pks : ciPrimaryKeys) {
            Integer hashCode = CommUtil.getCiMajorHashCode(pks);
            List<ESCIInfo> infos = ciHashCodeInfoMap.get(hashCode);
            if (infos == null || infos.isEmpty()) {
                continue;
            }
            // 比较业务主键值是否一样
            for (ESCIInfo info : infos) {
                try {
                    if (CommUtil.compareToCiPks(pks, com.binary.json.JSON.toList(info.getCiPrimaryKey(), String.class))) {
                        resultInfos.add(info);
                    }
                } catch (Exception e) {
                    log.error("do compareToCiPks 【" + JSON.toJSONString(ciPrimaryKeys) + "】 and 【 " + info.getCiPrimaryKey() + "】  err!", e);
                    throw MessageException.i18n("BS_MNAME_CIPRIMARYKEY_ERRO");
                }
            }
        }
        return resultInfos;
    }

    /**
     * 根据业务主键值集合生成hashCode集合
     *
     * @param ciPrimaryKeys 业务主键值集合
     * @return hashCodeSet
     */
    private Set<Integer> getHashCodesByPrimaryKeys(List<List<String>> ciPrimaryKeys) {
        if (ciPrimaryKeys == null || ciPrimaryKeys.isEmpty()) {
            return null;
        }
        Set<Integer> hashCodes = new HashSet<Integer>();
        for (List<String> pks : ciPrimaryKeys) {
            if (pks == null || pks.isEmpty()) {
                continue;
            }
            hashCodes.add(CommUtil.getCiMajorHashCode(pks));
        }
        return hashCodes;
    }

    public void transCIAttrs(List<ESCIInfo> esciInfos, boolean changeToShowName) {
        if (!BinaryUtils.isEmpty(esciInfos)) {
            Set<Long> classIds = esciInfos.stream().filter(info -> info.getClassId() != null).map(ESCIInfo::getClassId).collect(Collectors.toSet());
            //查分类
            List<ESCIClassInfo> ciClassInfos = classSvc.getListByQuery(0, classIds.size(),
                    QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("id", classIds))).getData();
            //父分类ids
            Set<Long> parentCiClassIds = ciClassInfos.stream()
                    .filter(c -> c.getParentId() != null && c.getParentId() != 0L)
                    .map(ESCIClassInfo::getParentId).collect(Collectors.toSet());
            Map<Long, ESCIClassInfo> parentCiClassInfoMap = new HashMap<>();
            if (!BinaryUtils.isEmpty(parentCiClassIds)) {
                List<ESCIClassInfo> parentCiClassInfos = classSvc.getListByQuery(0, classIds.size(),
                        QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("id", parentCiClassIds))).getData();
                parentCiClassInfoMap = parentCiClassInfos.stream().collect(Collectors.toMap(ESCIClassInfo::getId, e -> e));
                classIds.addAll(parentCiClassIds);
            }
            // 获取属性中间表记录，用于映射属性
            List<ESCIAttrTransConfig> attrConfigs = attrConfigSvc.getListByQuery(
                    QueryBuilders.boolQuery().must(QueryBuilders.termsQuery("classId", classIds)));
            Map<Long, List<ESCIAttrTransConfig>> attrConfigMap = BinaryUtils.toObjectGroupMap(attrConfigs, "classId");
            // 组装分类id与其所有属性的对应关系，包括父级属性
            Map<Long, List<CcCiAttrDef>> clsAlldefsMap = new HashMap<>();
            for (ESCIClassInfo classInfo : ciClassInfos) {
                clsAlldefsMap.put(classInfo.getId(), classInfo.getCcAttrDefs());
                if (classInfo.getParentId() != null && classInfo.getParentId() != 0L) {
                    ESCIClassInfo parClsInfo = parentCiClassInfoMap.get(classInfo.getParentId());
                    if (parClsInfo == null) {
                        continue;
                    }
                    clsAlldefsMap.get(classInfo.getId()).addAll(parClsInfo.getCcAttrDefs());
                    List<ESCIAttrTransConfig> parAttrConfigs = attrConfigMap.get(parClsInfo.getId());
                    if (!BinaryUtils.isEmpty(parAttrConfigs)) {
                        if (!attrConfigMap.containsKey(classInfo.getId())) {
                            attrConfigMap.put(classInfo.getId(), new ArrayList<>());
                        }
                        attrConfigMap.get(classInfo.getId()).addAll(parAttrConfigs);
                    }
                }
            }

            // CI属性转换
            for (ESCIInfo esciInfo : esciInfos) {
                List<CcCiAttrDef> defs = clsAlldefsMap.get(esciInfo.getClassId());
                // 判断CI所属分类存在，避免脏数据
                Assert.notEmpty(defs, "BS_MNAME_CLASS_NOT_EXSIT");
                List<ESCIAttrTransConfig> transConfigs = attrConfigMap.get(esciInfo.getClassId());
                Map<Object, ESCIAttrTransConfig> defConfigMap = BinaryUtils.toObjectMap(transConfigs, "defId");
                // 属性类型转换
                if (!changeToShowName) {
                    esciInfo.setAttrs(this.transCIAttrType(esciInfo.getAttrs(), defs, transConfigs));
                }
                // 原属性map
                Map<String, Object> attrs = esciInfo.getAttrs();
                // 只返回定义过的属性map
                Map<String, Object> transAttrs = new HashMap<>();
                for (CcCiAttrDef def : defs) {
                    ESCIAttrTransConfig attrConfig = defConfigMap.get(def.getId());
                    if (!BinaryUtils.isEmpty(attrConfig)) {
                        int targetType = attrConfig.getTargetAttrType() != null ? attrConfig.getTargetAttrType() : def.getProType();
                        // 转换为显示名称
                        if (changeToShowName) {
                            // 属性名称转换，修改过属性类型，实际属性值存储在目标字段中
                            if (!BinaryUtils.isEmpty(attrConfig.getTargetAttrName())) {
                                Object object = attrs.get(attrConfig.getTargetAttrName());
                                // attrs.remove(attrConfig.getTargetAttrName());
                                transAttrs.put(attrConfig.getShowName().toUpperCase(), object);
                                if (!BinaryUtils.isEmpty(object)) {
                                    // 转换时间显示格式
                                    if (targetType == 7) {
                                        Object dateStr = attrs.get(attrConfig.getTargetAttrName().concat("_date"));
                                        if (dateStr != null) {
                                            transAttrs.put(attrConfig.getShowName().toUpperCase(), dateStr);
                                        } else {
                                            transAttrs.put(attrConfig.getShowName().toUpperCase(), object);
                                        }
                                        // try {
                                        // long val = Long.parseLong(object.toString());
                                        // object = format.format(val);
                                        // } catch (Exception e) {
                                        // log.error("时间类型转换异常，保留原值返回[" + object + "]");
                                        // }
                                        // transAttrs.put(attrConfig.getShowName().toUpperCase(), object);
                                    }
                                    String transVal = object.toString();
                                    if (targetType == 2) {
                                        try {
                                            transVal = new BigDecimal(object.toString()).toPlainString();
                                        } catch (Exception e) {
                                        }
                                        transAttrs.put(attrConfig.getShowName().toUpperCase(), transVal);
                                    }
                                }
                            } else {
                                Object object = attrs.get(attrConfig.getSourceAttrName().toUpperCase());
                                // attrs.remove(attrConfig.getSourceAttrName().toUpperCase());
                                transAttrs.put(attrConfig.getShowName().toUpperCase(), object);
                                if (!BinaryUtils.isEmpty(object)) {
                                    // 转换时间显示格式
                                    if (targetType == 7) {
                                        Object dateStr = attrs.get(attrConfig.getSourceAttrName().toUpperCase().concat("_date"));
                                        if (dateStr != null) {
                                            transAttrs.put(attrConfig.getShowName().toUpperCase(), dateStr);
                                        } else {
                                            transAttrs.put(attrConfig.getShowName().toUpperCase(), object);
                                        }
                                        // try {
                                        // long val = Long.parseLong(object.toString());
                                        // object = format.format(val);
                                        // } catch (Exception e) {
                                        // log.error("时间类型转换异常，保留原值返回[" + object + "]");
                                        // }
                                        // transAttrs.put(attrConfig.getShowName().toUpperCase(), object);
                                    }
                                    String transVal = object.toString();
                                    if (targetType == 2) {
                                        try {
                                            transVal = new BigDecimal(object.toString()).toPlainString();
                                        } catch (Exception e) {
                                        }
                                        transAttrs.put(attrConfig.getShowName().toUpperCase(), transVal);
                                    }
                                }
                            }
                        } else {
                            // 转换为实际存储名称
                            if (!BinaryUtils.isEmpty(attrConfig.getTargetAttrName())) {
                                Object object = attrs.get(attrConfig.getShowName().toUpperCase());
                                // attrs.remove(attrConfig.getShowName().toUpperCase());
                                transAttrs.put(attrConfig.getTargetAttrName(), object);
                                if (targetType == 7) {
                                    // attrs.remove(attrConfig.getShowName().toUpperCase() + "_date");
                                    transAttrs.put(attrConfig.getTargetAttrName() + "_date", attrs.get(attrConfig.getShowName().toUpperCase() + "_date"));
                                }
                            } else {
                                Object object = attrs.get(attrConfig.getShowName().toUpperCase());
                                // attrs.remove(attrConfig.getShowName().toUpperCase());
                                transAttrs.put(attrConfig.getSourceAttrName().toUpperCase(), object);
                                if (targetType == 7) {
                                    // attrs.remove(attrConfig.getShowName().toUpperCase() + "_date");
                                    transAttrs.put(attrConfig.getSourceAttrName().toUpperCase() + "_date", attrs.get(attrConfig.getShowName().toUpperCase() + "_date"));
                                }
                            }
                        }
                    } else {
                        Object object = attrs.get(def.getProName().toUpperCase());
                        transAttrs.put(def.getProName().toUpperCase(), object);
                        if (!BinaryUtils.isEmpty(object)) {
                            // 转换时间显示格式
                            if (def.getProType().intValue() == 7) {
                                if (changeToShowName) {
                                    transAttrs.put(def.getProName().toUpperCase(), attrs.get(def.getProName().toUpperCase().concat("_date")));
                                } else {
                                    transAttrs.put(def.getProName().toUpperCase() + "_date", attrs.get(def.getProName().toUpperCase().concat("_date")));

                                }
                                // try {
                                // long val = Long.parseLong(object.toString());
                                // object = format.format(val);
                                // } catch (Exception e) {
                                // log.error("时间类型转换异常，保留原值返回[" + object + "]");
                                // }
                                // transAttrs.put(def.getProName().toUpperCase(), object);
                            }
                            if (changeToShowName) {
                                // 丰富ciLabel字段
                                String transVal = object.toString();
                                if (def.getProType().intValue() == 2) {
                                    try {
                                        transVal = new BigDecimal(object.toString()).toPlainString();
                                    } catch (Exception e) {
                                    }
                                    transAttrs.put(def.getProName().toUpperCase(), transVal);
                                }
                            }
                        }
                    }
                }
                // 丰富ciLabel
                if (changeToShowName) {
                    List<CcCiAttrDef> labelDefs = defs.stream().filter(def -> def.getIsCiDisp() != null && def.getIsCiDisp().intValue() == 1).collect(Collectors.toList());
                    List<String> ciLabels = new ArrayList<>();
                    for (CcCiAttrDef labelDef : labelDefs) {
                        ESCIAttrTransConfig esciAttrTransConfig = defConfigMap.get(labelDef.getId());
                        Object object ;
                        if(esciAttrTransConfig!=null){
                            object = transAttrs.get(esciAttrTransConfig.getShowName().toUpperCase());
                        }else {
                            object = transAttrs.get(labelDef.getProName().toUpperCase());
                        }
                        if (!BinaryUtils.isEmpty(object)) {
                            ciLabels.add(object.toString());
                        }
                    }
                    esciInfo.setCiLabel(JSON.toJSONString(ciLabels));
                }
                esciInfo.setAttrs(transAttrs);
            }
        }
    }

    private Map<String, Object> transCIAttrType(Map<String, Object> attrs, List<CcCiAttrDef> attrDefs, List<ESCIAttrTransConfig> transConfigs) {
        Map<String, Object> esAttr = new HashMap<String, Object>();
        if (attrs != null && !attrs.isEmpty()) {
            Map<Long, ESCIAttrTransConfig> attrConfigMap = BinaryUtils.toObjectMap(transConfigs, "defId");
            for (CcCiAttrDef def : attrDefs) {
                ESCIAttrTransConfig attrConfig = attrConfigMap.get(def.getId());
                // 通过中间表映射属性
                if (!BinaryUtils.isEmpty(attrConfig)) {
                    def.setProName(attrConfig.getShowName());
                    def.setProStdName(attrConfig.getShowName().toUpperCase());
                    if (attrConfig.getUpType().intValue() > 1) {
                        def.setProType(attrConfig.getTargetAttrType());
                    }
                }
            }
            Map<String, CcCiAttrDef> defMap = BinaryUtils.toObjectMap(attrDefs, "proStdName");
            // DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Iterator<Map.Entry<String, Object>> iterator = attrs.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> entry = iterator.next();
                String key = entry.getKey();
                if (BinaryUtils.isEmpty(entry.getValue())) {
                    continue;
                }
                String value = entry.getValue().toString();
                CcCiAttrDef def = defMap.get(key);
                if (!BinaryUtils.isEmpty(def)) {
                    Integer proType = def.getProType();
                    ESCIAttrTransConfig transConfig = attrConfigMap.get(def.getId());
                    if (transConfig != null && transConfig.getTargetAttrType() != null) {
                        proType = transConfig.getTargetAttrType();
                    }
                    PropertyType type = PropertyType.valueOf(proType);
                    // CI保存前已校验过属性，此处可以直接转换类型
                    switch (type) {
                        case INTEGER: {
                            esAttr.put(key, Long.valueOf(value));
                            break;
                        }
                        case DOUBLE: {
                            // 此处可以通过new BigDecimal(str2).setScale(4,
                            // BigDecimal.ROUND_HALF_UP).toPlainString()转换
                            // JSON.parseObject默认会使用BigDecimal转换，所以此处可不做
                            esAttr.put(key, Double.valueOf(value));
                            break;
                        }
                        case ENUM: {
                            esAttr.put(key, value);
                            break;
                        }
                        case DATE: {
                            // 日期类型目前未做校验，先按字符串存储
                            Date date = CheckAttrUtil.getDate(value, def.getConstraintRule());
                            if (date != null) {
                                esAttr.put(key, date.getTime());
                            } else {
                                log.error("[" + value + "]转换为时间类型出错！");
                            }
                            // 额外存储日期字符串，用于查询
                            esAttr.put(key + "_date", value);
                            break;
                        }
                        case VARCHAR: {
                            esAttr.put(key, value);
                            break;
                        }
                        case LONG_VARCHAR: {
                            esAttr.put(key, value);
                            break;
                        }
                        case ATTACHMENT:
                        case ATTACHMENT_ONLY_SHOW:
                        case PERSION:
                        case ORGANIZATION:
                        case CLOB: {
                            esAttr.put(key, value);
                            break;
                        }
                        case EXTERNAL_ASSET:
                        case EXTERNAL_ATTR: {
                            esAttr.put(key, value);
                            break;
                        }
                        default: {
                            esAttr.put(key, value);
                        }
                    }
                }
            }
        }
        return esAttr;
    }

    private String transSortField(Collection<Long> classIds, String sortField) {
        Assert.isTrue(!BinaryUtils.isEmpty(sortField), "X_PARAM_NOT_NULL${name:sortField}");
        // 分类为空时无法定位属性真实名称，默认按修改时间排序
        if (BinaryUtils.isEmpty(classIds)) {
            sortField = "modifyTime";
        }
        if ("ciCode".equals(sortField)) {
            sortField = "ciCode.keyword";
        }
        // 映射排序字段
        if (sortField.startsWith("attrs.")) {
            // 兼容attrs.属性名.keyword的传参方式
            String[] split = sortField.split("\\.");
            sortField = split.length > 1 ? split[1] : sortField;
            Long domainId = SysUtil.getCurrentUserInfo().getDomainId();
            List<ESCIClassInfo> classInfos = classSvc.getTargetAttrDefsByClassIds(domainId, classIds);
            CcCiAttrDef def = null;
            for (ESCIClassInfo clsInfo : classInfos) {
                for (CcCiAttrDef temDef : clsInfo.getCcAttrDefs()) {
                    if (temDef.getProName().equals(sortField)) {
                        def = temDef;
                    }
                }
            }
            if (!BinaryUtils.isEmpty(def)) {
                sortField = "attrs.".concat(def.getProStdName());
                Integer proType = def.getProType();
                if (proType.intValue() > 2 && proType.intValue() != PropertyType.DATE.getValue()) {
                    sortField += ".keyword";
                }
            } else {
                sortField += ".keyword";
            }
        }
        return sortField;
    }
    /**
     * 转换时保留attrs中的null值
     *
     * @param esciInfos
     * @return
     */
    private JSONArray writeMapNullValueForAttrs(List<ESCIInfo> esciInfos) {
        if (!BinaryUtils.isEmpty(esciInfos)) {
            return JSON.parseArray(JSON.toJSONString(esciInfos, new PropertyFilter() {

                @Override
                public boolean apply(Object object, String name, Object value) {
                    if (!(object instanceof HashMap) && value == null) {
                        return false;
                    }
                    return true;
                }
            }, SerializerFeature.WriteMapNullValue));
        }
        return new JSONArray();
    }

    @Override
    public ESCIInfo getById(Long id) {
        ESCIInfo esciInfo = super.getById(id);
        if (esciInfo != null) {
            this.transCIAttrs(Collections.singletonList(esciInfo), true);
        }
        return esciInfo;
    }

    @Override
    public Page<ESCIInfo> getListByQuery(int pageNum, int pageSize, QueryBuilder query) {
        Page<ESCIInfo> page = super.getListByQuery(pageNum, pageSize, query);
        this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public List<ESCIInfo> getListByQuery(QueryBuilder query) {
        List<ESCIInfo> list = super.getListByQuery(query);
        // this.transCIAttrs(list, true);
        return list;
    }

    @Override
    public List<ESCIInfo> getListByQueryScroll(QueryBuilder query) {
        List<ESCIInfo> list = super.getListByQueryScroll(query);
        // this.transCIAttrs(list, true);
        return list;
    }

    @Override
    public Page<ESCIInfo> getSortListByQuery(int pageNum, int pageSize, QueryBuilder query, String sortField, boolean isAsc) {
        Page<ESCIInfo> page = super.getSortListByQuery(pageNum, pageSize, query, sortField, isAsc);
        // this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public Page<ESCIInfo> getSortListByQuery(int pageNum, int pageSize, QueryBuilder query, List<SortBuilder<?>> sorts) {
        Page<ESCIInfo> page = super.getSortListByQuery(pageNum, pageSize, query, sorts);
        this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public Page<ESCIInfo> getSortListByHighLightQuery(int pageNum, int pageSize, QueryBuilder query, List<SortBuilder<?>> sorts, Collection<String> highLightFields) {
        Page<ESCIInfo> page = super.getSortListByHighLightQuery(pageNum, pageSize, query, sorts, highLightFields);
        this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public Page<ESCIInfo> getSortListByQuery(int pageNum, int pageSize, QueryBuilder searchQuery, QueryBuilder sortQuery) {
        Page<ESCIInfo> page = super.getSortListByQuery(pageNum, pageSize, searchQuery, sortQuery);
        this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public Page<ESCIInfo> getSortListByCdt(int pageNum, int pageSize, CCcCi searchCdt, CCcCi sortCdt) {
        Page<ESCIInfo> page = super.getSortListByCdt(pageNum, pageSize, searchCdt, sortCdt);
        // this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public Page<String> queryAttrVal(Long domainId, ESAttrAggBean bean) {
        if (!BinaryUtils.isEmpty(bean.getAttrName())) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.termQuery("classId", bean.getClassId()));
            query.must(QueryBuilders.termQuery("showName.keyword", bean.getAttrName()));
            List<ESCIAttrTransConfig> attrConfigs = attrConfigSvc.getListByQuery(query);
            if (!BinaryUtils.isEmpty(attrConfigs)) {
                ESCIAttrTransConfig attrConfig = attrConfigs.get(0);
                if (attrConfig.getUpType() != null && attrConfig.getUpType().longValue() > 1) {
                    bean.setAttrName("attrs." + attrConfig.getTargetAttrName());
                    bean.setAttrType(attrConfig.getTargetAttrType());
                } else {
                    bean.setAttrName("attrs." + attrConfig.getSourceAttrName().toUpperCase());
                    bean.setAttrType(attrConfig.getSourceAttrType());
                }
            } else {
                List<CcCiAttrDef> defs = classSvc.getAllDefsByClassId(domainId, bean.getClassId());
                Map<Object, CcCiAttrDef> defMap = BinaryUtils.toObjectMap(defs, "proName");
                CcCiAttrDef def = defMap.get(bean.getAttrName());
                Assert.notNull(def, "BS_MNAME_NOT_CI_ATTR_DEF");
                bean.setAttrName("attrs." + def.getProStdName());
                bean.setAttrType(def.getProType());
            }
        }
        return super.queryAttrVal(domainId, bean);
    }

    @Override
    public Page<Object> queryAttrValObj(Long domainId, ESAttrAggBean bean) {
        if (!BinaryUtils.isEmpty(bean.getAttrName())) {
            BoolQueryBuilder query = QueryBuilders.boolQuery();
            query.must(QueryBuilders.termQuery("classId", bean.getClassId()));
            query.must(QueryBuilders.termQuery("showName.keyword", bean.getAttrName()));
            List<ESCIAttrTransConfig> attrConfigs = attrConfigSvc.getListByQuery(query);
            if (!BinaryUtils.isEmpty(attrConfigs)) {
                ESCIAttrTransConfig attrConfig = attrConfigs.get(0);
                if (attrConfig.getUpType() != null && attrConfig.getUpType().longValue() > 1) {
                    bean.setAttrName("attrs." + attrConfig.getTargetAttrName());
                    bean.setAttrType(attrConfig.getTargetAttrType());
                } else {
                    bean.setAttrName("attrs." + attrConfig.getSourceAttrName().toUpperCase());
                    bean.setAttrType(attrConfig.getSourceAttrType());
                }
            } else {
                List<CcCiAttrDef> defs = classSvc.getAllDefsByClassId(domainId, bean.getClassId());
                Map<Object, CcCiAttrDef> defMap = BinaryUtils.toObjectMap(defs, "proName");
                CcCiAttrDef def = defMap.get(bean.getAttrName());
                Assert.notNull(def, "BS_MNAME_NOT_CI_ATTR_DEF");
                bean.setAttrName("attrs." + def.getProStdName());
                bean.setAttrType(def.getProType());
            }
        }
        return super.queryAttrValObj(domainId, bean);
    }

    @Override
    public Page<ESCIInfo> getListByCdt(int pageNum, int pageSize, CCcCi obj) {
        Page<ESCIInfo> page = super.getListByCdt(pageNum, pageSize, obj);
        // this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public Page<ESCIInfo> getSortListByCdt(int pageNum, int pageSize, CCcCi obj, List<SortBuilder<?>> sorts) {
        Page<ESCIInfo> page = super.getSortListByCdt(pageNum, pageSize, obj, sorts);
        // this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public Page<ESCIInfo> getSortListByCdt(int pageNum, int pageSize, CCcCi obj, String sortField, boolean isAsc) {
        Page<ESCIInfo> page = super.getSortListByCdt(pageNum, pageSize, obj, sortField, isAsc);
        // this.transCIAttrs(page.getData(), true);
        return page;
    }

    @Override
    public List<ESCIInfo> getListByCdt(CCcCi obj) {
        List<ESCIInfo> list = super.getListByCdt(obj);
        // this.transCIAttrs(list, true);
        return list;
    }

    @Override
    public List<ESCIInfo> getSortListByCdt(CCcCi obj, List<SortBuilder<?>> sorts) {
        List<ESCIInfo> list = super.getSortListByCdt(obj, sorts);
        // this.transCIAttrs(list, true);
        return list;
    }

    @Override
    public Long saveOrUpdate(ESCIInfo esciInfo) {
        this.transCIAttrs(Collections.singletonList(esciInfo), false);
        ciHistorySvc.saveOrUpdateHistoryInfo(esciInfo, ESCIHistoryInfo.ActionType.SAVE_OR_UPDATE);
        savePreOption(esciInfo);
        // SerializerFeature.WriteMapNullValue保留CI属性中的null值
        JSONObject attrObject = JSON.parseObject(JSON.toJSONString(esciInfo.getAttrs(), SerializerFeature.WriteMapNullValue));
        JSONObject json = JSON.parseObject(JSON.toJSONString(esciInfo));
        json.fluentPut("attrs", attrObject);
        return super.saveOrUpdate(json, true);
    }

    public Long saveOrUpdate(ESCIInfo esciInfo, Boolean isGenerateHistory) {
        this.transCIAttrs(Collections.singletonList(esciInfo), false);
        if (isGenerateHistory) {
            ciHistorySvc.saveOrUpdateHistoryInfo(esciInfo, ESCIHistoryInfo.ActionType.SAVE_OR_UPDATE);
        }
        savePreOption(esciInfo);
        // SerializerFeature.WriteMapNullValue保留CI属性中的null值
        JSONObject attrObject = JSON.parseObject(JSON.toJSONString(esciInfo.getAttrs(), SerializerFeature.WriteMapNullValue));
        JSONObject json = JSON.parseObject(JSON.toJSONString(esciInfo));
        json.fluentPut("attrs", attrObject);
        return super.saveOrUpdate(json, true);
    }

    @Override
    public Integer saveOrUpdateBatch(List<ESCIInfo> list) {
        SysUser loginUser = null;
        try {
            loginUser = SysUtil.getCurrentUserInfo();
        } catch (Exception e) {
        }
        for (ESCIInfo esCI : list) {
            if (esCI.getId() == null) {
                esCI.setId(ESUtil.getUUID());
                esCI.setCreator(loginUser == null ? "system" : loginUser.getLoginCode());
            }
            if (BinaryUtils.isEmpty(esCI.getCiCode())) {
                esCI.setCiCode(String.valueOf(esCI.getId()));
            }
        }
        this.transCIAttrs(list, false);
        list.forEach(obj -> savePreOption(obj));
        ciHistorySvc.saveOrUpdateHistoryInfosBatch(list, ESCIHistoryInfo.ActionType.SAVE_OR_UPDATE);
        return saveOrUpdateBatch(this.writeMapNullValueForAttrs(list), true);
    }

    public Integer saveOrUpdateBatch(List<ESCIInfo> list, Boolean isGenerateHistory) {
        SysUser loginUser = null;
        try {
            loginUser = SysUtil.getCurrentUserInfo();
        } catch (Exception e) {
        }
        for (ESCIInfo esCI : list) {
            if (esCI.getId() == null) {
                esCI.setId(ESUtil.getUUID());
                esCI.setCreator(loginUser == null ? "system" : loginUser.getLoginCode());
            }
            if (BinaryUtils.isEmpty(esCI.getCiCode())) {
                esCI.setCiCode(String.valueOf(esCI.getId()));
            }
        }
        this.transCIAttrs(list, false);
        list.forEach(obj -> savePreOption(obj));
        if (isGenerateHistory) {
            ciHistorySvc.saveOrUpdateHistoryInfosBatch(list, ESCIHistoryInfo.ActionType.SAVE_OR_UPDATE);
        }
        return saveOrUpdateBatch(this.writeMapNullValueForAttrs(list), true);
    }

    @Override
    public Map<String, Page<ESCIInfo>> getScrollByQuery(int pageNum, int pageSize, QueryBuilder query, String sortField, boolean isAsc) {
        Map<String, Page<ESCIInfo>> map = super.getScrollByQuery(pageNum, pageSize, query, sortField, isAsc);
        Iterator<Map.Entry<String, Page<ESCIInfo>>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            this.transCIAttrs(it.next().getValue().getData(), true);
        }
        return map;
    }

    @Override
    public boolean existByCondition(QueryBuilder query) {
        return super.existByCondition(query);
    }

    @Override
    public long countByCondition(QueryBuilder query) {
        return super.countByCondition(query);
    }

    @Override
    public List<ESCIInfo> getListByScroll(String scrollId) {
        List<ESCIInfo> list = super.getListByScroll(scrollId);
        this.transCIAttrs(list, true);
        return list;
    }

    /**
     * 根据属性名称清除对应分类CI的属性值
     *
     * @param classId
     * @param proName
     */
    public void clearCIAttrByProName(Long classId, String proName) {
        ESCIClassInfo cls = classSvc.getTargetAttrDefsByClassId(classId);
        for (CcCiAttrDef def : cls.getCcAttrDefs()) {
            if (def.getProName().equals(proName)) {
                Set<Long> classIds = new HashSet<>();
                classIds.add(classId);
                if (cls.getParentId().longValue() != 0L) {
                    // 子类属性值也要判断
                    classIds.add(cls.getParentId());
                }
                BoolQueryBuilder query = QueryBuilders.boolQuery();
                query.should(QueryBuilders.termsQuery("classId", classIds));
                this.updateByQuery(query, "ctx._source.attrs.remove('" + def.getProStdName() + "')", false);
            }
        }
    }

    /**
     * 刷新CI主键
     *
     * @param classId 分类id
     * @param ciPKAttrDefNames 所有主键属性名称
     */
    public void updateCIPrimaryKeys(Long classId, List<String> ciPKAttrDefNames) {
        ESCIClassInfo classInfo = classSvc.getTargetAttrDefsByClassId(classId);
        Map<String, CcCiAttrDef> defMap = BinaryUtils.toObjectMap(classInfo.getCcAttrDefs(), "proName");
        String primaryKeyScript = "ctx._source.ciPrimaryKey='[";
        for (String name : ciPKAttrDefNames) {
            CcCiAttrDef def = defMap.get(name);
            Assert.notNull(def, "主键定义不存在");
            if (ciPKAttrDefNames.indexOf(name) > 0) {
                primaryKeyScript += ",";
            }
            primaryKeyScript += "\"'+ctx._source.attrs['" + def.getProStdName() + "']+'\"";
        }
        Set<Long> classIds = new HashSet<>();
        classIds.add(classId);
        if (classInfo.getParentId().longValue() != 0L) {
            // 子类属性值也要判断
            classIds.add(classInfo.getParentId());
        }
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.should(QueryBuilders.termsQuery("classId", classIds));
        this.updateByQuery(query, primaryKeyScript + "]'", false);
    }

    public CiGroupPage queryPageBySearchBeanVO(ESCISearchBeanVO bean, boolean hasClass) {
        Page<ESCIInfo> page = this.searchESCIByBeanVO(bean);
        CiGroupPage ciGroupPage = commSvc.tranCiGroupPage(page, hasClass);
        if (hasClass && CollectionUtils.isEmpty(ciGroupPage.getClassInfos()) && !CollectionUtils.isEmpty(bean.getClassIds())) {
            Long domainId = SysUtil.getCurrentUserInfo().getDomainId();
            List<ESCIClassInfo> classInfos = classSvc.getAllDefESClassInfosByClassIds(domainId, bean.getClassIds());
            if (classInfos != null) {
                List<CcCiClassInfo> classInfoList = new ArrayList<>();
                for (ESCIClassInfo esClsInfo : classInfos) {
                    CcCiClassInfo classInfo = commSvc.tranCcCiClassInfo(esClsInfo);
                    classInfoList.add(classInfo);
                }
                ciGroupPage.setClassInfos(classInfoList);
            }
        }
        return ciGroupPage;
    }

    private Page<ESCIInfo> searchESCIByBeanVO(ESCISearchBeanVO bean) {
        BoolQueryBuilder query = (BoolQueryBuilder)commSvc.getCIQueryBuilderByBean(bean);
        if (StringUtils.isNotEmpty(bean.getGteTime())) {
            Long gteTime = convertTime(bean.getGteTime());
            query.must(QueryBuilders.rangeQuery("createTime").gte(gteTime));
        }
        if (StringUtils.isNotEmpty(bean.getLteTime())) {
            Long lteTime = convertEndTime(bean.getLteTime());
            query.must(QueryBuilders.rangeQuery("createTime").lte(lteTime));
        }
        String sort = !BinaryUtils.isEmpty(bean.getSortField()) ? bean.getSortField() : "modifyTime";
        // 映射排序字段
        Set<Long> classIds = new HashSet<>();
        if (!BinaryUtils.isEmpty(bean.getClassIds())) {
            classIds.addAll(bean.getClassIds());
        }
        if (bean.getCdt() != null && bean.getCdt().getClassId() != null) {
            classIds.add(bean.getCdt().getClassId());
        }
        sort = this.transSortField(classIds, sort);
        if (bean.isHighLight()) {
            SortOrder orderType = bean.isAsc() ? SortOrder.ASC : SortOrder.DESC;
            List<SortBuilder<?>> sorts = new LinkedList<>();
            sorts.add(SortBuilders.fieldSort(sort).order(orderType));
            if (bean.getUsage() == 1) {
                return this.getSortListByHighLightQuery(bean.getPageNum(), bean.getPageSize(), query, sorts, bean.getHighLightFields());
            } else if (bean.getUsage() == 0) {
                return iamsCIDesignNonComplianceDao.getSortListByHighLightQuery(bean.getPageNum(), bean.getPageSize(), query, sorts, bean.getHighLightFields());
            }
        } else {
            if (bean.getUsage() == 1) {
                return this.getSortListByQuery(bean.getPageNum(), bean.getPageSize(), query, sort, bean.isAsc());
            } else if (bean.getUsage() == 0) {
                return iamsCIDesignNonComplianceDao.getSortListByQuery(bean.getPageNum(), bean.getPageSize(), query, sort, bean.isAsc());
            }
        }
        return new Page<>();
    }

    public Long convertEndTime(String lteTime) {
        String replace = lteTime.replace("/", "")+"240000";
        return Long.valueOf(replace);
    }

    public Long convertTime(String convertTime) {
        String replace = convertTime.replace("/", "")+"000000";
        return Long.valueOf(replace);
    }

    public Page<ESCIInfo> getSwitchListByQuery(int pageNum, int pageSize, TermsQueryBuilder query, Integer usage) {
        if (usage == 1) {
            Page<ESCIInfo> page = super.getListByQuery(pageNum, pageSize, query);
            this.transCIAttrs(page.getData(), true);
            return page;
        }else{
            Page<ESCIInfo> page = iamsCIDesignNonComplianceDao.getListByQuery(pageNum, pageSize, query);
            this.transCIAttrs(page.getData(), true);
            return page;
        }
    }

    public Map<String, Page<ESCIInfo>> getSwitchScrollByQuery(int pageNum, int pageSize, BoolQueryBuilder query, String sortField, boolean isAsc, Integer usage) {
        if (usage == 1) {
            Map<String, Page<ESCIInfo>> map = super.getScrollByQuery(pageNum, pageSize, query, sortField, isAsc);
            Iterator<Map.Entry<String, Page<ESCIInfo>>> it = map.entrySet().iterator();
            while (it.hasNext()) {
                this.transCIAttrs(it.next().getValue().getData(), true);
            }
            return map;
        }else{
            Map<String, Page<ESCIInfo>> map = iamsCIDesignNonComplianceDao.getScrollByQuery(pageNum, pageSize, query, sortField, isAsc);
            Iterator<Map.Entry<String, Page<ESCIInfo>>> it = map.entrySet().iterator();
            while (it.hasNext()) {
                this.transCIAttrs(it.next().getValue().getData(), true);
            }
            return map;

        }
    }

    public List<ESCIInfo> getSwitchListByScroll(String scrollId,Integer usage) {
        if (usage == 1) {
            List<ESCIInfo> list = super.getListByScroll(scrollId);
            this.transCIAttrs(list, true);
            return list;
        }else{
            List<ESCIInfo> list = iamsCIDesignNonComplianceDao.getListByScroll(scrollId);
            this.transCIAttrs(list, true);
            return list;
        }
    }
}